import { _decorator, Component, Node, view, TransformBit, Widget, SpriteFrame, Vec3, UITransform, CCFloat,game } from "cc"
import { EDITOR_NOT_IN_PREVIEW } from "cc/env"
const { ccclass, property, executeInEditMode,disallowMultiple,menu } = _decorator
// const EDITOR_NOT_IN_PREVIEW = false

// 使用ccenum定义枚举
enum DeviceOrientationEnum {
  IPhoneX_Portrait = 4618,
  IPhone6_Portrait = 5622,
  IPad_Portrait = 7500,
  IPad_Landscape = 13333,
  IPhone6_Landscape = 17787,
  IPhoneX_Landscape = 21653,
}

const RATIO_UNIT = 10000
const DESIGN_WIDTH = 1334
const DESIGN_HEIGHT = 750
@ccclass("IMobileType")
class IMobileType {
  @property({ visible: true, tooltip: "节点位置" })
  position: Vec3 = new Vec3(0, 0, 0)

  @property({ visible: true, tooltip: "节点缩放" })
  scale: Vec3 = new Vec3(0, 0, 0)

  @property({ type: CCFloat, visible: true, tooltip: "节点旋转" })
  angle: number = 0

  @property({ visible: false, tooltip: "是否被初始化" })
  isInit: boolean = false

  constructor() {
    this.position = new Vec3(0, 0, 0)
    this.scale = new Vec3(0, 0, 0)
    this.angle = 0
  }
}

@ccclass("AdaptScreen")
@executeInEditMode(true)
@disallowMultiple(true)
@menu("adaptScreen/AdaptScreen")
export class AdaptScreen extends Component {

  private resolutionChangedTime: number = 0

  private ratio: DeviceOrientationEnum = DeviceOrientationEnum.IPad_Portrait

  @property({ type: IMobileType, displayName: "IPhone6_Portrait" })
  iPhone6Portrait: IMobileType = new IMobileType()
  @property({ type: IMobileType, displayName: "iPhone6_Landscape" })
  iPhone6Landscape: IMobileType = new IMobileType()
  @property({ type: IMobileType, displayName: "IPhoneX_Portrait" })
  iPhoneXPortrait: IMobileType = new IMobileType()
  @property({ type: IMobileType, displayName: "IPhoneX_Landscape" })
  iPhoneXLandscape: IMobileType = new IMobileType()
  @property({ type: IMobileType, displayName: "IPad_Portrait" })
  iPadPortrait: IMobileType = new IMobileType()
  @property({ type: IMobileType, displayName: "iPad_Landscape" })
  iPadLandscape: IMobileType = new IMobileType()

  private iMobileType: IMobileType = null

  constructor() {
    super()
    this.resolutionChangedTime = 0
  }

  onLoad() {
    if (EDITOR_NOT_IN_PREVIEW) {
      //节点改变位置、旋转或缩放事件。如果具体需要判断是哪一个事件，可通过判断回调的第一个参数类型是 Node.TransformBit 中的哪一个来获取
      this.node.on(Node.EventType.TRANSFORM_CHANGED, this.saveTransformData, this)
      //当节点尺寸改变时触发的事件。 性能警告：这个事件会在每次对应的属性被修改时触发，如果事件回调损耗较高，有可能对性能有很大的负面影响，请尽量避免这种情况。
      this.node.on(Node.EventType.SIZE_CHANGED, this.saveTransformSize, this)
      //   this.node.on(Node.EventType.ANCHOR_CHANGED, this.saveTransformAnchorPoint, this)
      view.on("editor-canvas-resize", this.onEditorSizeChanged, this)
      //@ts-ignore
      this.onEditorSizeChanged(view.editorCanvasSizeRatio)
    } else {
      game.on("window-resize",this.onResizeEvent,this)
      this.onResizeEvent()
    }
  }

  protected onDestroy(): void {
    if (EDITOR_NOT_IN_PREVIEW) {
      this.node.off(Node.EventType.TRANSFORM_CHANGED, this.saveTransformData, this)
      this.node.off(Node.EventType.SIZE_CHANGED, this.saveTransformSize, this)
      view.off("editor-canvas-resize", this.onEditorSizeChanged, this)
    } else {
      game.off("window-resize",this.onResizeEvent,this)
    }
  }

  onResizeEvent(){
    const size = view.getDesignResolutionSize()
    const ratio = Math.round(size.width / size.height * RATIO_UNIT) 
    this.updateTransformData(ratio)
  }

  onEditorSizeChanged(ratio: number) {
    if (Date.now() - this.resolutionChangedTime < 100) return
    this.resolutionChangedTime = Date.now()
    this.ratio = ratio
    this.initIMobileType()
    this.iMobileType = this.getNearestRatioData(ratio)
    this.updateTransformData(this.ratio)
  }

  saveTransformData(transformBit: TransformBit) {
    if (Date.now() - this.resolutionChangedTime < 100) return
    this.resolutionChangedTime = Date.now()

    if (transformBit && transformBit == Node.TransformBit.SCALE) {
      this.iMobileType.scale = this.node.getScale()
    }
    if (transformBit && transformBit == Node.TransformBit.ROTATION) {
      this.iMobileType.angle = this.node.eulerAngleZ
    }
    if (transformBit && transformBit == Node.TransformBit.POSITION) {
      this.iMobileType.position = this.node.getPosition()
    }
    this.updateCurrentMobileType(this.iMobileType)
  }

  saveTransformSize(){}

  updateTransformData(ratio: number) {
    if(ratio === undefined) return
    let currentMobileType = this.getNearestRatioData(ratio)
    this.node.setPosition(currentMobileType.position)
    this.node.setScale(currentMobileType.scale)
    this.node.eulerAngleZ = currentMobileType.angle
  }

  private getNearestRatioData(ratio: number): IMobileType {
    let minDifference = Infinity
    let nearestIndex = -1
    const deviceOrientations: DeviceOrientationEnum[] = [
      DeviceOrientationEnum.IPad_Portrait,
      DeviceOrientationEnum.IPad_Landscape,
      DeviceOrientationEnum.IPhone6_Portrait,
      DeviceOrientationEnum.IPhone6_Landscape,
      DeviceOrientationEnum.IPhoneX_Portrait,
      DeviceOrientationEnum.IPhoneX_Landscape,
    ]
    for (let index = 0; index < deviceOrientations.length; index++) {
      const currentDifference = Math.abs(deviceOrientations[index] - ratio)
      if (currentDifference < minDifference) {
        minDifference = currentDifference
        nearestIndex = index
      }
    }
    ratio = deviceOrientations[nearestIndex]

    let iMobileType: IMobileType = null
    switch (ratio) {
      case DeviceOrientationEnum.IPhone6_Portrait: {
        iMobileType = this.iPhone6Portrait
        break
      }
      case DeviceOrientationEnum.IPhone6_Landscape: {
        iMobileType = this.iPhone6Landscape
        break
      }
      case DeviceOrientationEnum.IPhoneX_Portrait: {
        iMobileType = this.iPhoneXPortrait
        break
      }
      case DeviceOrientationEnum.IPhoneX_Landscape: {
        iMobileType = this.iPhoneXLandscape
        break
      }
      case DeviceOrientationEnum.IPad_Portrait: {
        iMobileType = this.iPadPortrait
        break
      }
      case DeviceOrientationEnum.IPad_Landscape: {
        iMobileType = this.iPadLandscape
        break
      }
    }
    return iMobileType
  }

  updateCurrentMobileType(currentMobileType: IMobileType) {
    currentMobileType.position = this.node.getPosition()
    currentMobileType.scale = this.node.getScale()
    currentMobileType.angle = this.node.eulerAngles.z
  }

  private initIMobileType() {
    let iMobileTypes: IMobileType[] = [
      this.iPhone6Portrait,
      this.iPhone6Landscape,
      this.iPhoneXPortrait,
      this.iPhoneXLandscape,
      this.iPadPortrait,
      this.iPadLandscape,
    ]
    for (let key in iMobileTypes) {
      if (!iMobileTypes[key].isInit) {
        iMobileTypes[key].isInit = true
        this.updateCurrentMobileType(iMobileTypes[key])
      }
    }
  }
}
